#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>

// 标准数据类型的别名声明文件

#include <stdint.h>

// 表示空
#define null NULL
// 表示逻辑假
#define false 0
// 表示逻辑真
#define true 1

// 表示字节(1byte char)
typedef char Byte;
// 表示字符(1byte char)
typedef char Char;
// 表示短整数(2byte short)
typedef short Short;
// 表示整数(4byte int)
typedef int32_t Int;
// 表示长整数(8byte long long)
typedef int64_t Long;
// 表示单精度浮点数(4byte float)
typedef float Float;
// 表示双精度浮点数(8byte double)
typedef double Double;
// 表示无符号字节(1byte unsigned char)
typedef unsigned char UnsignedByte;
// 表示无符号字符(1byte unsigned char)
typedef unsigned char UnsignedChar;
// 表示无符号短整数(2byte unsigned short)
typedef unsigned short UnsignedShort;
// 表示无符号整数(4byte unsigned int)
typedef uint32_t UnsignedInt;
// 表示无符号长整数(8byte unsigned long long)
typedef uint64_t UnsignedLong;

void printUUID(char*);
Int checkUUID(char*);
void seedRandomWithTime();
Long currentTimeMillis();
void println(char* string);

Int main(Int argc, char* argv[]) {
    if (argc == 2) {
        if (!strcmp(argv[1], "random")) {
            char allows[17] = "0123456789abcdef";
            seedRandomWithTime();
            char chars[33];
            for (Int i = 0; i < 32; i++) {
                chars[i] = allows[rand() % 16];
            }
            chars[32] = '\0';
            printUUID(chars);
        } else {
            if (checkUUID(argv[1])) {
                printUUID(argv[1]);
            } else {
                println("错误的UUID");
                return -1;
            }
        }
    } else {
        printf("用法: %s <uuid/\"random\">\n", argv[0]);
        return 1;
    }
    return 0;
}

void printUUID(char* c) {
    if (strlen(c) == 32) {
        println(c);
        char copy[37];
        Int ci = 0;
        copy[8] = '-';
        copy[13] = '-';
        copy[18] = '-';
        copy[18] = '-';
        copy[23] = '-';
        for (Int i = 0; i < 32; i++) {
            if (copy[ci] == '-') ci++;
            copy[ci] = c[i];
            ci++;
        }
        copy[36] = '\0';
        println(copy);
    } else if (strlen(c) == 36) {
        char copy[33];
        Int ci = 0;
        for (Int i = 0; i < 36; i++) {
            switch (i) {
                case 8:
                case 13:
                case 18:
                case 23:
                    i++;
                default:
                    copy[ci] = c[i];
                    ci++;
            }
        }
        copy[32] = '\0';
        println(copy);
        println(c);
    }
}

Int checkUUID(char* c) {
    Int digest = strlen(c);
    if (digest != 32 && digest != 36) return false;
    for (Int i = 0; i < digest; i++) {
        if ((c[i] >= 'a' && c[i] <= 'f') || (c[i] >= '0' && c[i] <= '9') || c[i] == '-') {
            continue;
        } else return false;
    }
    return true;
}

void seedRandomWithTime() {
    srand((UnsignedInt) currentTimeMillis());
}

void println(char *string) {
    printf("%s\n", string);
}

Long currentTimeMillis() {
    struct timeval tv;
    gettimeofday(&tv, null);
    Long sec = tv.tv_sec;
    Long usec = tv.tv_usec;
    return sec * 1000 + usec / 1000;
}